/*
 * ScenarioView.cpp
 *
 *  Created on: 01/06/2014
 *      Author: javier
 */

#include "ScenarioView.h"
#include "BZPView.h"

ScenarioView::ScenarioView(BZPView* view, BZPModel* model, SDLWindow* window) :
		factory(window) {
	this->view = view;
	this->model = model;
	width = height = 0;
	idTarget = -1;
}

void ScenarioView::setScenarioDimensions(int x, int y) {
	Lock l(m);
	cam.setLevelWidthTiles(x);
	cam.setLevelHeightTiles(y);
	width = x;
	height = y;
	int id = -5000;
		for (int i = 0; i < height; ++i) {
			for (int j = 0; j < width; ++j) {
				Positionable* object = new Positionable(id--, j, i, GROUND);
	//			newObject(id++, i + 0.5, j + 0.5, GROUND);
				Drawable* newView = factory.create(object);
				viewsBackgroundList.push_back(newView);
			}
		}
}

ScenarioView::~ScenarioView() {
	// TODO Auto-generated destructor stub
}

void ScenarioView::add(Positionable* positionable) {
	Lock l(m);
	Drawable* newView = factory.create(positionable);
	views[positionable->getId()] = newView;
	if (positionable->getModelObjectType() == ZOMBIE_SPAWN || positionable->getModelObjectType() == BOMBERMAN_SPAWN){
		viewsBackgroundList.push_back(newView);
	} else {
		viewsList.push_back(newView);
	}

	if (positionable->getId() == idTarget){
		cam.setTarget(positionable);
	}
}

void ScenarioView::update() {
	Lock l(m);
	std::list<Drawable*>::iterator iter;
	for (iter = viewsList.begin(); iter != viewsList.end(); ++iter) {
		Drawable* drawable = *iter;
		drawable->update();
	}
	cam.update();
}

void ScenarioView::render() {
	Lock l(m);
	std::list<Drawable*>::iterator iter;
	for (iter = viewsBackgroundList.begin(); iter != viewsBackgroundList.end();
			++iter) {
		Drawable* drawable = *iter;
		drawable->render(cam);
	}
	for (iter = viewsList.begin(); iter != viewsList.end(); ++iter) {
		Drawable* drawable = *iter;
		drawable->render(cam);
	}
}

void ScenarioView::setTarget(Positionable* p) {
	Lock l(m);
	if (p) idTarget = p->getId();
	cam.setTarget(p);
}

void ScenarioView::handleClick(int x, int y) {
}

void ScenarioView::clear() {
	Lock l(m);
	views.clear();
	cam.setTarget(NULL);
	std::list<Drawable*>::iterator iter;
	for (iter = viewsList.begin(); iter != viewsList.end(); ++iter) {
		delete (*iter);
	}
	for (iter = viewsBackgroundList.begin(); iter != viewsBackgroundList.end(); ++iter) {
		delete (*iter);
	}
	viewsList.clear();
	viewsBackgroundList.clear();
}

void ScenarioView::removeView(int id) {
	Lock l(m);
	Drawable* drawable = views[id];
	std::list<Drawable*>::iterator iter;
	for (iter = viewsList.begin(); iter != viewsList.end(); ++iter) {
		Drawable* d = *iter;
		if (drawable == d) {
			viewsList.erase(iter);
			break;
		}
	}
	views.erase(id);
	if (id == idTarget){
		cam.setTarget(NULL);
	}
}

void ScenarioView::addExplosion(Positionable* positionable) {
	Lock l(m);
	if (positionable->getModelObjectType() == BOMB){
		int range = properties.getPropertyAsInt("bomb_range");
		int x = positionable->getX();
		Positionable *p = new Positionable(0, positionable->getX(), positionable->getY(), EXPLOSION);
		Drawable* centerView = factory.createExplosion(p);
		viewsList.push_back(centerView);
		for (int i = 0; i < range; ++i){
			p->setX(++x);
			Drawable* newView = factory.createExplosion(p);
			viewsList.push_back(newView);
		}
		x = positionable->getX();
		for (int i = 0; i < range; ++i){
			p->setX(--x);
			Drawable* newView = factory.createExplosion(p);
			viewsList.push_back(newView);
		}
		p->setX(positionable->getX());
		int y = positionable->getY();
		for (int i = 0; i < range; ++i){
			p->setY(++y);
			Drawable* newView = factory.createExplosion(p);
			viewsList.push_back(newView);
		}
		y = positionable->getY();
		for (int i = 0; i < range; ++i){
			p->setY(--y);
			Drawable* newView = factory.createExplosion(p);
			viewsList.push_back(newView);
		}
	} else {
		Drawable* newView = factory.createExplosion(positionable);
	//	views[positionable->getId()] = newView;
		viewsList.push_back(newView);
	}
}
